#ifndef HELMETUART_H
#define HELMETUART_H

#include "HelmetSystemConfig.h"
#include "HelmetTimers.h"
#include "HelmetI2C.h"

/**************************************************************************************
	Definitions
**************************************************************************************/
// Atom
#define ATOM UART1
#define ATOM_HANDLER void __ISR(_UART1_VECTOR,ipl4)IntUart1Handler(void)

// GPS
#define GPS UART2
#define GPS_HANDLER void __ISR(_UART2_VECTOR,ipl5)IntUART2Handler(void)

/**************************************************************************************
	Function Prototypes
**************************************************************************************/
void WriteAtom(const char *string);
void WriteGPS(const char *string);
void ConfigAtom( void );
void ConfigGPS( void );

/**************************************************************************************
	Functions
**************************************************************************************/

void ConfigAtom() {
	// Configuration
	UARTConfigure( ATOM, UART_ENABLE_PINS_TX_RX_ONLY);
    UARTSetFifoMode( ATOM, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY);
    UARTSetLineControl( ATOM, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1);
    UARTSetDataRate( ATOM, GetPeripheralClock(), 38400 );
    UARTEnable( ATOM, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX));
    
    // Interrupt setup
    INTEnable( INT_SOURCE_UART_RX(ATOM), INT_ENABLED );
    INTSetVectorPriority( INT_VECTOR_UART(ATOM), INT_PRIORITY_LEVEL_4 );
    INTSetVectorSubPriority( INT_VECTOR_UART(ATOM), INT_SUB_PRIORITY_LEVEL_0 );	
}

void ConfigGPS() {
	// Configuration
	UARTConfigure( GPS, UART_ENABLE_PINS_TX_RX_ONLY );
    UARTSetFifoMode( GPS, UART_INTERRUPT_ON_TX_NOT_FULL | UART_INTERRUPT_ON_RX_NOT_EMPTY );
    UARTSetLineControl( GPS, UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1 );
    UARTSetDataRate( GPS, GetPeripheralClock(), 38400 );
    UARTEnable( GPS, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_RX | UART_TX) );
    
    // Interrupt setup
	INTEnable( INT_SOURCE_UART_RX(GPS), INT_ENABLED );
    INTSetVectorPriority(INT_VECTOR_UART(GPS), INT_PRIORITY_LEVEL_5);
    INTSetVectorSubPriority(INT_VECTOR_UART(GPS), INT_SUB_PRIORITY_LEVEL_0);
}

// Write string to Atom
void WriteAtom(const char *string)
{
    while(*string != '\0')
    {
        while( !UARTTransmitterIsReady(ATOM) );
        UARTSendDataByte( ATOM, *string );
        string++;
        while( !UARTTransmissionHasCompleted(ATOM) );
    }
}

// Write string to GPS
void WriteGPS(const char *string)
{
    while(*string != '\0')
    {
        while( !UARTTransmitterIsReady(GPS) );
        UARTSendDataByte( GPS, *string );
        string++;
        while( !UARTTransmissionHasCompleted(GPS) );
    }
}

/**************************************************************************************
	Interrupt handling routines
**************************************************************************************/
// Note: Priority 1 (lowest) to 7 (highest)

/**************************************
		ATOM (UART 1)
			Priority 4
**************************************/
ATOM_HANDLER
{
	unsigned int atomdata;
		
	if(( INTGetFlag( INT_SOURCE_UART_RX(ATOM) ) )) {
		
		// Get Atom data byte
		atomdata = UARTGetDataByte( ATOM );
		
		// Echo Atom data byte to GPS
		UARTSendDataByte(GPS, atomdata );
		
		// Toggle LED to indicate UART activity
		SetAtomLED();
		
		// Make sure the flag is cleared
		INTClearFlag( INT_SOURCE_UART_RX(ATOM) );
	}
	
	// Don't care about TX interrupt
	if(( INTGetFlag( INT_SOURCE_UART_TX(ATOM) ) )) {
		INTClearFlag( INT_SOURCE_UART_TX(ATOM) );
	}
}	

/**************************************
		GPS (UART 2)
			Priority 5
**************************************/
GPS_HANDLER
{
	unsigned int gpsdata;
	
	// Is this an RX interrupt?
	if(( INTGetFlag( INT_SOURCE_UART_RX(GPS) ) )) {

		// Get GPS data byte
		gpsdata = UARTGetDataByte( GPS );
		
		// Echo GPS data byte to Atom
		//UARTSendDataByte( ATOM, gpsdata );
		
		// TODO: put data in buffer
		
		// If the second is old,
		//   initiate a new second
		//   instruct main to perform adc conversion
		// Note: this effectively 'debounces' the multiple
		//       characters coming in from the GPS. The
		//       first new character begins a 'new second'.
		//       The timer sets the second as 'old' just 
		//       before the new second is expected to start
		//       long after the GPS will have sent its data.
		if( isOldSecond() ) {
			startNewSecond();
			//StartADC();
			MainCheckFuelGauge++;
		}
		
		// Toggle LED to indicate UART activity
		SetGPSLED();
		
		// Make sure the flag is cleared
		INTClearFlag( INT_SOURCE_UART_RX(GPS) );
	}

	// Don't care about TX interrupt
	if ( INTGetFlag(INT_SOURCE_UART_TX(GPS)) ) {
		INTClearFlag(INT_SOURCE_UART_TX(GPS));
	}
}

#endif